--[[
WarlockReminder 2.1.7
Date: 2013-05-22T14:27:29Z
Author: cklausi
Original Author of WarlockReminder: Vux of Dragonblight-US 
]]--

WarlockReminder = LibStub("AceAddon-3.0"):NewAddon("WarlockReminder", "AceConsole-3.0", "AceEvent-3.0", "AceTimer-3.0")
local L = LibStub("AceLocale-3.0"):GetLocale("WarlockReminder")
local media = LibStub("LibSharedMedia-3.0")

-- Default Values
local defaults = {
    profile = {
		--Reminder
		ReminderEnable = true,
		showSL = true,
		showGOS = true,
		showFlask = true,
		showPet = true,
		showFood = true,
		showDI = true,
		ScanPartyInCombat = false,
		showDemonicRebirth = true,
		-- Pets
		petAffliction = "felhunter",
		petDemonology = "felguard",
		petDestruction = "imp",
		-- DS
		DrainSoulEnable = true,
		DrainSoulSound = "Quaddamage",
		DrainSoulPercent = 20 / 100,
		DrainSoulHealth = 100,
		-- Shadowburn
		ShadowburnEnable = true,
		ShadowburnSound = "Clearcasting",
		-- Backdraft
		BackdraftEnable = true,
		-- MoltenCore
		MoltenCoreEnable = true,
		MoltenCoreSound = "Clearcasting",
		-- Shadow Trance
		ShadowTranceEnable = true,
		ShadowTranceSound = "Clearcasting",
		-- Demonic Fury
		DemonicFuryEnable = true,
		DemonicFuryFadeout = 0.5,
		-- Burning Embers
		BurningEmbersEnable = true,
		BurningEmbersFadeout = 0.5,
		BurningEmbersSegment = false,
		-- Conflagrate
		ConflagrateEnable = true,
		-- Soul Shards
		SoulShardsEnable = true,
		SoulShardFadeout = 0.5,
		-- Cooldowns
		CooldownEnable = true,
		ShowCd = true,
		ShowCdOnlyInCombat = true,
		-- Reminder
		ReminderFontsize = 11,
		ReminderFont = "Friz Quadrata TT",
		ReminderTop = (UIParent:GetHeight()/2), 
		ReminderLeft = (UIParent:GetWidth()/2)-60,
		ReminderAlpha = 1,
		ReminderSize = 64,
		ReminderExpand = "down",
		-- Combat
		CombatEnable = true,
		showCombatTimeleft = true,
		CombatFontsize = 11,
		CombatFont = "Friz Quadrata TT",
		CombatTop = (UIParent:GetHeight()/2), 
		CombatLeft = (UIParent:GetWidth()/2),
		CombatAlpha = 1,
		CombatSize = 64,
		CombatExpand = "down",
		-- Cooldown
		CooldownFontsize = 11,
		CooldownFont = "Friz Quadrata TT",
		CooldownTop = (UIParent:GetHeight()/2), 
		CooldownLeft = (UIParent:GetWidth()/2),
		CooldownAlpha = 1,
		CooldownSize = 64,
		CooldownExpand = "down",
		CooldownFadeout = 0.5,
		-- Custom
		CustomEnable = true,
		CustomSound = "Clearcasting",
		showCustomTimeleft = true,
		ShowCustomOnlyInCombat = true,
		CustomFontsize = 12,
		CustomFont = "Friz Quadrata TT",
		CustomTop = (UIParent:GetHeight()/2),
		CustomLeft = (UIParent:GetWidth()/2)+60,
		CustomAlpha = 1,
		CustomSize = 64,
		CustomExpand = "down",
		CustomSpells = {}
    },
}
-- END Default Values

-- Spell Ids
local SoulLink = 108415
local DrainSoul = 1120
local Shadowburn = 17877
local SoulFire = 6353
local DemonicRebirth = 88448
local GrimoireOfSacrifice = 108503
local DemonicFury = 104315
local BurningEmbers = 108647
local SoulShards = 117198
local DarkIntent = 109773
local Backdraft = 117828
local Conflagrate = 17962
-- CDs {SpellId, TalentPosition, SpellSpec}
local CombatCDs = {
	ImpSwarm = {
		104316, 0, 2
	},
	Soulstone = {
		20707, 0, 0
	},
	DarkRegeneration = {
		108359, 1, 0
	},
	HowlOfTerror = {
		5484, 4, 0
	},
	ArchimondesVengeance = {
		108505, 16, 0
	},
	MortalCoil = {
		6789, 5, 0
	},
	SacrificialPact = {
		108416, 8, 0
	},
	GrimoireOfService = {
		108501, 14, 0
	},
	Shadowfury = {
		30283, 6, 0
	},
	DarkBargain = {
		110913, 9, 0
	},
	UnboundWill = {
		108482, 12, 0
	},
	GrimoireOfSacrifice = {
		108503, 15, 0
	},
	CarrionSwarm = {
		103967, 0, 2
	},
	DarkSoulInstability = {
		113858, 0, 3
	},
	DarkSoulKnowledge = {
		113861, 0, 2
	},
	DarkSoulMisery = {
		113860, 0, 1
	},
	DemonicCircleTeleport = {
		48020, 0, 0
	},
	DemonicLeap = {
		109151, 0, 2
	},
	Soulshatter = {
		29858, 0, 0
	},
	SummonDoomguard = {
		18540, 0, 0
	},
	TwilightWard = {
		6229, 0, 0
	},
	UnendingResolve = {
		104773, 0, 0
	},
	Havoc = {
		80240, 0, 3
	},
	FlamesOfXoroth = {
		120451, 0, 3
	},
}
local CooldownOptions = {}
local i = 1
for index, value in pairs(CombatCDs) do
	CooldownOptions[index] = {
		type = "toggle",
		order  = i,
		name = select(1, GetSpellInfo(value[1])),
		desc = select(1, GetSpellInfo(value[1])),
		get = "getDynamicOption",
		set = "setDynamicOption",
	}
	i = i+1
end

-- Flask
-- Wotlk
local FlaskOfFrostwyrm = 53755
-- Cata
local FlaskOfTheDraconicMind = 79470
-- Mop
local FlaskOfTheWarmSun = 105691

local CurrentFlask = FlaskOfTheWarmSun

-- Well Fed
local WellFed = 57399 -- there are so many different buffs - using textures
local  _, _, WellFedIcon = GetSpellInfo(WellFed)

-- Pets
local Pets = {
	["imp"] = 688,
	["voidwalker"] = 697,
	["succubus"] = 712,
	["felhunter"] = 691,
	["felguard"] = 30146,
}

-- Procs
local MoltenCore = 122355
local ShadowTrance = 17941

-- Variables
local wlrDB
local wlrBuff = {}
local timeLeft = 0
local timeelapsed = 0
local DiTimeElapsed = 0
local CustomPlayed = false
local CustomShow = false
local DrainSoulPlayed = false
local ShadowburnPlayed = false
local ReminderPlayed = false
local DemonicRebirthPlayed = false
local _, englishClass = UnitClass("player")
local SelectedSpells = {}
local SelectedCooldowns = {}
local ConfigMode = false
local Spec = GetSpecialization(false, false)
local PetBattle = false

-- Frames
local ReminderFrame
local ReminderIcons
local CombatFrame
local CombatIcons
local CooldownFrame
local CooldownIcons
local CustomFrame
local CustomIcons
local UnlockDialog

-- Addon start
function WarlockReminder:OnInitialize()
	if(englishClass == "WARLOCK") then
		self.db = LibStub("AceDB-3.0"):New("WarlockReminderDB", defaults, "Default")
		
		self.db.RegisterCallback(self, "OnProfileChanged", "OnProfileChanged")
		self.db.RegisterCallback(self, "OnProfileCopied", "OnProfileChanged")
		self.db.RegisterCallback(self, "OnProfileReset", "OnProfileReset")
		self.db.RegisterCallback(self, "OnNewProfile", "OnNewProfile")
		
		wlrDB = self.db.profile
		
		self:CreateFrames()
		
		self:ReminderFrameSetup()
		
		self:SetUpOptions()
	end
end

function WarlockReminder:CreateDefaultTables()
	wlrDB.CustomSpells = {
		[89937] = 89937,
		[70840] = 70840,
	}
end

function WarlockReminder:OnEnable()
	if(englishClass == "WARLOCK") then
		self:RegisterEvent("PLAYER_TARGET_CHANGED")
		self:RegisterEvent("ACTIVE_TALENT_GROUP_CHANGED")
		self:RegisterEvent("PLAYER_SPECIALIZATION_CHANGED")
		self:RegisterEvent("PET_BATTLE_OPENING_START")
		self:RegisterEvent("PET_BATTLE_CLOSE")
		
		media:Register("sound", "Quaddamage", "Interface\\AddOns\\WarlockReminder\\Sounds\\quaddamage.ogg")
		media:Register("sound", "Clearcasting", "Sound\\Spells\\Clearcasting_Impact_Chest.wav")
		
		Spec = GetSpecialization(false, false)
	end
end
-- END Addon start

local function round(number, decimals)
    return (("%%.%df"):format(decimals)):format(number)
end

local function GetTimeLeft(expirationTime)
	if(expirationTime == 0 or expirationTime == nil or tonumber(expirationTime) == nil) then 
		timeleft = "" 
	else 
		timeleft = (-1*(GetTime()-expirationTime))
		if(timeleft > 120) then 
			timeleft = timeleft / 60
			timeleft = tostring(ceil(timeleft)) .. L["minutes"]
		else
			timeleft = tostring(round(timeleft, 1)) .. L["seconds"]
		end
	end
	
	return timeleft
end

-- Check if the unit has a buff
local function UnitHasBuff(unit, buff)
    for i=1, 40 do
		local name, _, iconTexture, count, _, _, expirationTime, source, _ = UnitBuff(unit, i)
        if ( name == GetSpellInfo(buff) ) then
			return true, iconTexture, count, expirationTime, source
        end
    end
	return false
end

-- EVENTS
function WarlockReminder:PLAYER_TARGET_CHANGED()
	if(ConfigMode == false) then
		DrainSoulPlayed = false
		ShadowburnPlayed = false
	end
end

function WarlockReminder:ACTIVE_TALENT_GROUP_CHANGED()
	Spec = GetSpecialization(false, false)
end

function WarlockReminder:PLAYER_SPECIALIZATION_CHANGED()
	Spec = GetSpecialization(false, false)
end

function WarlockReminder:PET_BATTLE_OPENING_START()
	ReminderFrame:Hide()
	CooldownFrame:Hide()
	CombatFrame:Hide()
	CustomFrame:Hide()
end

function WarlockReminder:PET_BATTLE_CLOSE()
	ReminderFrame:Show()
	CooldownFrame:Show()
	CombatFrame:Show()
	CustomFrame:Show()
end
-- END EVENTS

-- Warlock reminder
function WarlockReminder:Reminder()

	-- Bufffood
	if(DiTimeElapsed > 3) then -- Throttled
		if(wlrDB.showFood and
			UnitLevel("target") < 0 and
			UnitHealth("target") * 100 / UnitHealthMax("target") > 98 and
			select(2, UnitHasBuff("player", WellFed)) ~= WellFedIcon
		) then
			ReminderIcons[WellFed]:Show()
		else
			ReminderIcons[WellFed]:Hide()
		end
	end

	-- Flask
	if(DiTimeElapsed > 3) then -- Throttled
		if(wlrDB.showFlask and
			UnitLevel("target") < 0 and
			UnitHealth("target") * 100 / UnitHealthMax("target") > 98 and
			-- Wotlk
			wlrBuff[FlaskOfFrostwyrm] == nil and
			-- Cata
			wlrBuff[FlaskOfTheDraconicMind] == nil and
			-- Mop
			wlrBuff[FlaskOfTheWarmSun] == nil
		) then
			ReminderIcons[CurrentFlask]:Show()
		else
			ReminderIcons[CurrentFlask]:Hide()
		end
	end
	
	-- GrimoireOfSacrifice
	local _, _, _, _, selectedGOS, _ = GetTalentInfo(15)
	if(selectedGOS and
		wlrDB.showGOS and
		not IsMounted("player") and
		wlrBuff[GrimoireOfSacrifice] == nil
	) then
		ReminderIcons[GrimoireOfSacrifice]:Show()
	else
		ReminderIcons[GrimoireOfSacrifice]:Hide()
	end

	-- Soul Link
	local _, _, _, _, selectedSL, _ = GetTalentInfo(7)
	if(selectedSL and
		wlrDB.showSL and
		not IsMounted("player") and
		wlrBuff[SoulLink] == nil
	) then
		ReminderIcons[SoulLink]:Show()
	else
		ReminderIcons[SoulLink]:Hide()
	end
	
	-- DI
	if(DiTimeElapsed > 3) then -- Throttle DiScanner
		if( wlrDB.showDI
		) then
			local party = ""
			local count = 1
			local DiMiss = 0
			
			DiTimeElapsed = 0
			
			if(UnitInRaid("player")) then
				party = "raid"
				count = 40
			elseif(UnitInParty("player")) then
				party = "party"
				count = 4
			end
			
			if((InCombatLockdown() == 1 and wlrDB.ScanPartyInCombat == true) or InCombatLockdown() == nil) then
				if(party == "raid" or party == "party") then
					for i = 1, count, 1 do
						if 	UnitExists(party..i) and
							not UnitHasBuff(party..i, DarkIntent) and
							not UnitHasBuff(party..i, 1459) and -- Mage
							not UnitHasBuff(party..i, 61316) and -- Mage Dalaran
							not UnitHasBuff(party..i, 126309) and -- Hunterpet
							not UnitHasBuff(party..i, 77747) and -- Shaman
							not UnitHasBuff(party..i, 21562) and -- Priest Stamina
							not UnitHasBuff(party..i, 469) and -- Warrior Stamina
							not UnitHasBuff(party..i, 90364) -- Hunterpet Stamina
						then 
							DiMiss = DiMiss+1 
						end				
					end
				end
			end
			-- Scan player when not in party
			if(wlrBuff[DarkIntent] == nil and 
				wlrBuff[1459] == nil and 
				wlrBuff[61316] == nil and 
				wlrBuff[126309] == nil and 
				wlrBuff[77747] == nil and 
				wlrBuff[21562] == nil and 
				wlrBuff[469] == nil and 
				wlrBuff[90364] == nil and 
				(party == "party" or party == "")
			) then 
				DiMiss = DiMiss+1 
			end
			
			if(DiMiss > 0) then
				ReminderIcons[DarkIntent].text:SetText(tostring(DiMiss) .. " " .. L["missing"])
				ReminderIcons[DarkIntent]:Show()
			else
				ReminderIcons[DarkIntent]:Hide()
			end
		else
			ReminderIcons[DarkIntent]:Hide()
		end
	end

	-- Pet
	if(wlrDB.showPet and
		not selectedGOS and
		not UnitExists("pet") and
		not IsMounted("player")
	) then
		if(Spec == 1) then ReminderIcons["pets"].texture:SetTexture(GetSpellTexture(Pets[wlrDB.petAffliction])) -- Affli
		elseif(Spec == 2) then ReminderIcons["pets"].texture:SetTexture(GetSpellTexture(Pets[wlrDB.petDemonology])) -- Demo
		elseif(Spec == 3)then ReminderIcons["pets"].texture:SetTexture(GetSpellTexture(Pets[wlrDB.petDestruction])) -- Destro
		else ReminderIcons["pets"].texture:SetTexture(GetSpellTexture(Pets["imp"])) end --unknown
		ReminderIcons["pets"]:Show()
	else
		ReminderIcons["pets"]:Hide()
	end

	self:RefreshReminder(ReminderIcons, ReminderFrame, wlrDB.ReminderAlpha, wlrDB.ReminderSize, wlrDB.ReminderLeft, wlrDB.ReminderTop, wlrDB.ReminderFont, wlrDB.ReminderFontsize, wlrDB.ReminderExpand)
	if(wlrDB.ReminderEnable == false) then ReminderFrame:Hide()
	else ReminderFrame:Show() end
end

function WarlockReminder:Power(PowerType, Segment)
	if(Segment == false) then Segment = nil end
	local Value = UnitPower("player", PowerType, Segment)
	local Max = UnitPowerMax("player", PowerType, Segment)
	local Percent = 0
	if(Max > 0) then Percent = Value / Max end
	
	return Percent, Value
end

-- Combat reminder
function WarlockReminder:CombatReminder()
		
	-- Demonic Rebirth
	if(wlrDB.showDemonicRebirth and 
		wlrBuff[DemonicRebirth] ~= nil
	) then
		if(wlrDB.showCombatTimeleft) then
			local _, _, _, expirationTime = strsplit(";", wlrBuff[DemonicRebirth])
			local timeleft = GetTimeLeft(expirationTime)
			CombatIcons[DemonicRebirth].text:SetText(timeleft)
		else
			CombatIcons[DemonicRebirth].text:SetText("")
		end
		CombatIcons[DemonicRebirth]:Show()
	else
		CombatIcons[DemonicRebirth]:Hide()
	end
	
	-- Drain Soul
	if(wlrDB.DrainSoulEnable and 
		Spec == 1 and
		UnitCanAttack("player", "target") and
		not UnitIsDead("target") and
		UnitHealth("target") > 0 and
		UnitHealth("target") * 100 / UnitHealthMax("target") <= wlrDB.DrainSoulPercent * 100 and
		UnitHealthMax("target") >= tonumber(wlrDB.DrainSoulHealth)
	) then
		CombatIcons[DrainSoul]:Show()
		if(not DrainSoulPlayed) then
			PlaySoundFile(media:Fetch("sound", wlrDB.DrainSoulSound))
			DrainSoulPlayed = true
		end
	else
		DrainSoulPlayed = false
		CombatIcons[DrainSoul]:Hide()
	end
	
	-- Shadowburn
	if(wlrDB.ShadowburnEnable and 
		Spec == 3 and
		UnitCanAttack("player", "target") and
		not UnitIsDead("target") and
		UnitHealth("target") > 0 and
		UnitHealth("target") * 100 / UnitHealthMax("target") <= 0.2 * 100
	) then
		CombatIcons[Shadowburn]:Show()
		if(not ShadowburnPlayed) then
			PlaySoundFile(media:Fetch("sound", wlrDB.ShadowburnSound))
			ShadowburnPlayed = true
		end
	else
		ShadowburnPlayed = false
		CombatIcons[Shadowburn]:Hide()
	end
	
	-- Backdraft
	if(wlrDB.BackdraftEnable and 
		wlrBuff[Backdraft] ~= nil
	) then
		local _, _, count, expirationTime = strsplit(";", wlrBuff[Backdraft])
		local timeleft = 0
		if(wlrDB.showCombatTimeleft) then
			timeleft = GetTimeLeft(expirationTime)
		else
			timeleft = ""
		end
		CombatIcons[Backdraft].text2:SetText(tostring(count).."x")
		CombatIcons[Backdraft].text:SetText(timeleft)
		CombatIcons[Backdraft]:Show()
	else
		CombatIcons[Backdraft]:Hide()
	end
	
	-- Conflagrate
	if(wlrDB.ConflagrateEnable and 
		Spec == 3
	) then
		local currentCharges, maxCharges, timeLastCast, cooldownDuration = GetSpellCharges(Conflagrate)
		local timeleft = 0
		if(wlrDB.showCombatTimeleft and (currentCharges < maxCharges)) then
			timeleft = ("%.01f"):format(cooldownDuration - (GetTime() - timeLastCast))
		else
			timeleft = ""
		end
		CombatIcons[Conflagrate].text2:SetText(tostring(currentCharges).."x")
		CombatIcons[Conflagrate].text:SetText(timeleft)
		CombatIcons[Conflagrate]:Show()
	else
		CombatIcons[Conflagrate]:Hide()
	end
	
	-- Moltencore
	if(wlrDB.MoltenCoreEnable and 
		wlrBuff[MoltenCore] ~= nil
	) then
		local _, _, count, expirationTime = strsplit(";", wlrBuff[MoltenCore])
		local timeleft = 0
		if(wlrDB.showCombatTimeleft) then
			timeleft = GetTimeLeft(expirationTime)
		else
			timeleft = ""
		end
		CombatIcons[MoltenCore].text2:SetText(tostring(count).."x")
		CombatIcons[MoltenCore].text:SetText(timeleft)
		CombatIcons[MoltenCore]:Show()
		if(not MoltenCorePlayed) then
			PlaySoundFile(media:Fetch("sound", wlrDB.MoltenCoreSound))
			MoltenCorePlayed = true
		end
	else
		CombatIcons[MoltenCore]:Hide()
		MoltenCorePlayed = false
	end
	
	-- Shadowtrance
	if(wlrDB.ShadowTranceEnable and 
		wlrBuff[ShadowTrance] ~= nil
	) then
		if(wlrDB.showCombatTimeleft) then
			local _, _, _, expirationTime = strsplit(";", wlrBuff[ShadowTrance])
			local timeleft = GetTimeLeft(expirationTime)
			CombatIcons[ShadowTrance].text:SetText(timeleft)
		else
			CombatIcons[ShadowTrance].text:SetText("")
		end
		CombatIcons[ShadowTrance]:Show()
		if(not ShadowTrancePlayed) then
			PlaySoundFile(media:Fetch("sound", wlrDB.ShadowTranceSound))
			ShadowTrancePlayed = true
		end
	else
		CombatIcons[ShadowTrance]:Hide()
		ShadowTrancePlayed = false
	end
	
	-- Soul Shards
	if(wlrDB.SoulShardsEnable and
		Spec == 1
	) then
		local Percent, Value = self:Power(SPELL_POWER_SOUL_SHARDS)
		if(Percent < wlrDB.SoulShardFadeout) then Percent = wlrDB.SoulShardFadeout end
		CombatIcons[SoulShards].text:SetText(tostring(Value))
		CombatIcons[SoulShards]:SetAlpha(Percent)
		CombatIcons[SoulShards]:Show()
	else
		CombatIcons[SoulShards]:Hide()
	end
	
	-- Demonic Fury
	if(wlrDB.DemonicFuryEnable and
		Spec == 2
	) then
		local Percent, Value = self:Power(SPELL_POWER_DEMONIC_FURY)
		if(Percent < wlrDB.DemonicFuryFadeout) then Percent = wlrDB.DemonicFuryFadeout end
		CombatIcons[DemonicFury].text:SetText(tostring(Value))
		CombatIcons[DemonicFury]:SetAlpha(Percent)
		CombatIcons[DemonicFury]:Show()
	else
		CombatIcons[DemonicFury]:Hide()
	end
	
	-- Burning Embers
	if(wlrDB.BurningEmbersEnable and
		Spec == 3
	) then
		local Percent, Value = self:Power(SPELL_POWER_BURNING_EMBERS, wlrDB.BurningEmbersSegment)
		if(Percent < wlrDB.BurningEmbersFadeout) then Percent = wlrDB.BurningEmbersFadeout end
		if(wlrDB.BurningEmbersSegment) then text = tostring(floor(Value/10)) .. " - " .. tostring(mod(Value, 10))
		else text = tostring(Value) end
		CombatIcons[BurningEmbers].text:SetText(text)
		CombatIcons[BurningEmbers]:SetAlpha(Percent)
		CombatIcons[BurningEmbers]:Show()
	else
		CombatIcons[BurningEmbers]:Hide()
	end

	self:RefreshReminder(CombatIcons, CombatFrame, wlrDB.CombatAlpha, wlrDB.CombatSize, wlrDB.CombatLeft, wlrDB.CombatTop, wlrDB.CombatFont, wlrDB.CombatFontsize, wlrDB.CombatExpand)
	if(wlrDB.CombatEnable == false) then CombatFrame:Hide()
	else CombatFrame:Show() end
end

-- Cooldown reminder
function WarlockReminder:CooldownReminder()
	self:RefreshReminder(CooldownIcons, CooldownFrame, wlrDB.CooldownAlpha, wlrDB.CooldownSize, wlrDB.CooldownLeft, wlrDB.CooldownTop, wlrDB.CooldownFont, wlrDB.CooldownFontsize, wlrDB.CooldownExpand)
	for index, spell in pairs(CombatCDs) do
		if(self:CombatSpell(spell[1], spell[2], spell[3]) == true and wlrDB[index] == true) then
			self:CombatCooldown(CooldownIcons, spell[1])
		else
			CooldownIcons[spell[1]]:Hide()
		end
	end
	
	if(wlrDB.CooldownEnable == false) then CooldownFrame:Hide()
	else CooldownFrame:Show() end
end

function WarlockReminder:CombatSpell(SpellId, TalentPosition, SpellSpec)
	local selected = 0
	if(SpellSpec == Spec or SpellSpec == 0) then
		if(TalentPosition ~= 0) then _, _, _, _, selected, _ = GetTalentInfo(TalentPosition) end
		if(selected == true or TalentPosition == 0) then
			return true
		else
			return false
		end
	else
		return false
	end
end

function WarlockReminder:CombatCooldown(Icons, Spell)
	local start, duration, enabled = GetSpellCooldown(Spell)
	if(duration < 1.5) then
		Icons[Spell].text:SetText(L["Ready!"])
		if(InCombatLockdown() == nil and wlrDB.ShowCdOnlyInCombat) then
			Icons[Spell]:Hide()
		else
			Icons[Spell]:Show()
		end
	elseif(start > 0 and duration > 1.5 and wlrDB.ShowCd) then
		local timeleft = start + duration - GetTime()
		if(timeleft > 120) then
			timeleft = tostring(ceil(timeleft/60)) .. L["minutes"]
		else
			timeleft = tostring(round(timeleft, 1)) .. L["seconds"]
		end
		Icons[Spell].text:SetText(timeleft)
		if(InCombatLockdown() == nil and wlrDB.ShowCdOnlyInCombat) then
			Icons[Spell]:Hide()
		else
			Icons[Spell]:SetAlpha(wlrDB.CooldownFadeout)
			Icons[Spell]:Show()
		end
	else
		Icons[Spell]:Hide()
	end
end

-- Custom reminder
function WarlockReminder:CustomReminder()
	for index, spell in pairs(wlrDB.CustomSpells) do
		if(CustomIcons[index] ~= nil) then
			if(wlrBuff[index] ~= nil) then
				local _, _, count, expirationTime = strsplit(";", wlrBuff[index])
				local timeleft = 0
				if(wlrDB.showCustomTimeleft and tonumber(expirationTime) > 0) then
					timeleft = GetTimeLeft(expirationTime)
				else
					timeleft = ""
				end
				if(count == "0" or count == nil) then count = "" 
				else count = tostring(count).."x" end
				CustomIcons[index].text2:SetText(count)
				CustomIcons[index].text:SetText(timeleft)
				CustomIcons[index]:Show()
			else
				CustomIcons[index]:Hide()
			end
		end
	end	
	
	self:RefreshReminder(CustomIcons, CustomFrame, wlrDB.CustomAlpha, wlrDB.CustomSize, wlrDB.CustomLeft, wlrDB.CustomTop, wlrDB.CustomFont, wlrDB.CustomFontsize, wlrDB.CustomExpand)
	if(wlrDB.CustomEnable == false or (InCombatLockdown() == nil and wlrDB.ShowCustomOnlyInCombat)) then CustomFrame:Hide()
	else CustomFrame:Show() end
end

function WarlockReminder:GetUnitBuffs(unit)
	wipe(wlrBuff)
	for i = 1, 40 do
		local name, _, iconTexture, count, _, _, expirationTime, _, _, _, spellId = UnitBuff(unit, i)
		if(not tContains(wlrBuff, spellId) and spellId ~= nil) then
			wlrBuff[spellId] = name .. ";" .. iconTexture .. ";" .. count .. ";" .. expirationTime
		end
    end
end

-- OnUpdate
function WarlockReminder:OnUpdate(self, elapsed)
	-- Throttle for DiScanner
	DiTimeElapsed = DiTimeElapsed + elapsed
	timeelapsed = timeelapsed + elapsed
	if(timeelapsed >= 0.1) then
		if(ConfigMode == false) then
			WarlockReminder:GetUnitBuffs("player")
			WarlockReminder:Reminder()
			WarlockReminder:CombatReminder()
			WarlockReminder:CooldownReminder()
			WarlockReminder:CustomReminder()
		end
	  timeelapsed = 0
	end
end

-- Reminderfactory
function WarlockReminder:NewReminder(SpellIds, Alpha, Size, Left, Top, Font, Fontsize)
	local f = CreateFrame("Frame", nil, UIParent)
	f:SetToplevel(1)
	f:SetPoint("CENTER",0,0)
	f:SetAlpha(Alpha)
	f:SetFrameStrata("BACKGROUND")
	f:SetWidth(Size) 
	f:SetHeight(#SpellIds*f:GetWidth())
	
	-- Move
	f:SetScript("OnMouseDown", 
		function(self)
			if(self:IsMovable() == 1) then
				self:StartMoving()
			end
		end
	)
	f:SetScript("OnEvent",function(self,event,...) self[event](self,event,...) end)
	
	local i = {}
	local j = 0
	for index, value in pairs(SpellIds) do
		i[value] = self:CreateIcon(f, Size, Alpha, value, Font, Fontsize)
	end
			
	f:SetScript("OnUpdate", function(self, elapsed)
			WarlockReminder:OnUpdate(self, elapsed)
		end
	)
	
	f:Show()
	
	return f, i
end

function WarlockReminder:CreateIcon(Frame, Size, Alpha, Texture, Font, Fontsize)
	local i = CreateFrame("Frame", nil, Frame)
	i:SetAlpha(Alpha)
	i:SetFrameStrata("BACKGROUND")
	i:SetWidth(Size)
	i:SetHeight(Size)
	i:SetPoint("TOP", Frame, "TOP", 0, 0)
	
	local t = i:CreateTexture(nil, "BACKGROUND")
	if(Texture == "pets") then t:SetTexture(GetSpellTexture(Pets["imp"]))
	else t:SetTexture(GetSpellTexture(Texture)) end
	t:SetAllPoints(i)
	i.texture = t
	
	local text = i:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
	text:SetFont(media:Fetch("font", Font), Fontsize, "OUTLINE")
	text:SetPoint("BOTTOMRIGHT",-1,3)
	i.text = text
	
	local text2 = i:CreateFontString(nil, "OVERLAY", "GameFontHighlight")
	text2:SetFont(media:Fetch("font", Font), Fontsize, "OUTLINE")
	text2:SetPoint("BOTTOMRIGHT",-1,3+Fontsize)
	i.text2 = text2
	
	i:Show()
	
	return i
end

function WarlockReminder:RefreshReminder(Icons, Reminder, Alpha, Size, Left, Top, Font, Fontsize, Expand)
	local i = 0
	Reminder:ClearAllPoints()
	for index, value in pairs(Icons) do
		Icons[index]:ClearAllPoints()
		if(Icons[index]:IsShown()) then
			if(Expand == "down") then 
				Reminder:SetWidth(Size) 
				Reminder:SetHeight((i+1)*Reminder:GetWidth())
				Reminder:SetPoint("TOP", UIParent, "BOTTOMLEFT", Left, Top)
			elseif(Expand == "up") then
				Reminder:SetWidth(Size) 
				Reminder:SetHeight((i+1)*Reminder:GetWidth())
				Reminder:SetPoint("BOTTOM", UIParent, "BOTTOMLEFT", Left, Top)
			elseif(Expand == "left") then
				Reminder:SetHeight(Size) 
				Reminder:SetWidth((i+1)*Reminder:GetHeight())
				Reminder:SetPoint("RIGHT", UIParent, "BOTTOMLEFT", Left, Top)
			else
				Reminder:SetHeight(Size) 
				Reminder:SetWidth((i+1)*Reminder:GetHeight())
				Reminder:SetPoint("LEFT", UIParent, "BOTTOMLEFT", Left, Top)
			end
			Icons[index]:SetWidth(Size)
			Icons[index]:SetHeight(Size)
			
			if(Expand == "down") then 
				Icons[index]:SetPoint("TOP", Reminder, "TOP", 0, -(i*Size))
			elseif(Expand == "up") then
				Icons[index]:SetPoint("BOTTOM", Reminder, "BOTTOM", 0, i*Size)
			elseif(Expand == "left") then
				Icons[index]:SetPoint("RIGHT", Reminder, "RIGHT", -(i*Size), 0)
			else
				Icons[index]:SetPoint("LEFT", Reminder, "LEFT", i*Size, 0)
			end
			Icons[index].text:SetFont(media:Fetch("font", Font), Fontsize, "OUTLINE")
			Icons[index].text:SetPoint("BOTTOMRIGHT",-1,3)
			Icons[index].text2:SetPoint("BOTTOMRIGHT",-1,3+Fontsize)
			Icons[index].text2:SetFont(media:Fetch("font", Font), Fontsize, "OUTLINE")
			if(index ~= BurningEmbers and index ~= SoulShards and index ~= DemonicFury) then Icons[index]:SetAlpha(Alpha) end
			i = i+1
		end
	end
end

-- Create Frames
function WarlockReminder:CreateFrames()
	ReminderFrame, ReminderIcons = self:NewReminder({SoulLink, GrimoireOfSacrifice, "pets", DarkIntent,
														CurrentFlask, WellFed},
													wlrDB.ReminderAlpha, wlrDB.ReminderSize, wlrDB.ReminderLeft, wlrDB.ReminderTop, 
													wlrDB.ReminderFont, wlrDB.ReminderFontsize)
													
	ReminderFrame:SetScript("OnMouseUp",
		function(self) 
			if(self:IsMovable() == 1) then
				self:StopMovingOrSizing() 
				if(wlrDB.ReminderExpand == "right") then 
					wlrDB.ReminderLeft = self:GetLeft()
					wlrDB.ReminderTop = self:GetTop() - (self:GetHeight() / 2)
				else
					wlrDB.ReminderLeft = self:GetLeft() + (self:GetWidth() /2)
					wlrDB.ReminderTop = self:GetTop()
				end
			end
		end
	)
	self:RefreshReminder(ReminderIcons, ReminderFrame, wlrDB.ReminderAlpha, wlrDB.ReminderSize, wlrDB.ReminderLeft, wlrDB.ReminderTop, wlrDB.ReminderFont, wlrDB.ReminderFontsize, wlrDB.ReminderExpand)
	
	CombatFrame, CombatIcons = self:NewReminder({DrainSoul, Shadowburn, MoltenCore, ShadowTrance, Backdraft, Conflagrate, DemonicRebirth, DemonicFury, BurningEmbers, SoulShards,
													},
													wlrDB.CombatAlpha, wlrDB.CombatSize, wlrDB.CombatLeft, wlrDB.CombatTop, 
													wlrDB.CombatFont, wlrDB.CombatFontsize)
													
	CombatFrame:SetScript("OnMouseUp",
		function(self) 
			if(self:IsMovable() == 1) then
				self:StopMovingOrSizing()
				if(wlrDB.CombatExpand == "right") then 
					wlrDB.CombatLeft = self:GetLeft()
					wlrDB.CombatTop = self:GetTop() - (self:GetHeight() / 2)
				else
					wlrDB.CombatLeft = self:GetLeft() + (self:GetWidth() /2)
					wlrDB.CombatTop = self:GetTop()
				end
			end
		end
	)
	self:RefreshReminder(CombatIcons, CombatFrame, wlrDB.CombatAlpha, wlrDB.CombatSize, wlrDB.CombatLeft, wlrDB.CombatTop, wlrDB.CombatFont, wlrDB.CombatFontsize, wlrDB.CombatExpand)
	
	
	CustomFrame, CustomIcons = self:NewReminder(wlrDB.CustomSpells,
												wlrDB.CustomAlpha, wlrDB.CustomSize, wlrDB.CustomLeft, wlrDB.CustomTop,
												wlrDB.CustomFont, wlrDB.CustomFontsize)
	CustomFrame:SetScript("OnMouseUp",
		function(self) 
			if(self:IsMovable() == 1) then
				self:StopMovingOrSizing() 
				if(wlrDB.CustomExpand == "right") then 
					wlrDB.CustomLeft = self:GetLeft()
					wlrDB.CustomTop = self:GetTop() - (self:GetHeight() / 2)
				else
					wlrDB.CustomLeft = self:GetLeft() + (self:GetWidth() /2)
					wlrDB.CustomTop = self:GetTop()
				end 
			end
		end
	)
	self:RefreshReminder(CustomIcons, CustomFrame, wlrDB.CustomAlpha, wlrDB.CustomSize, wlrDB.CustomLeft, wlrDB.CustomTop, wlrDB.CustomFont, wlrDB.CustomFontsize, wlrDB.CustomExpand)
	
	CooldownFrame, CooldownIcons = self:NewReminder({},
													wlrDB.CooldownAlpha, wlrDB.CooldownSize, wlrDB.CooldownLeft, wlrDB.CooldownTop, 
													wlrDB.CooldownFont, wlrDB.CooldownFontsize)
													
	CooldownFrame:SetScript("OnMouseUp",
		function(self) 
			if(self:IsMovable() == 1) then
				self:StopMovingOrSizing()
				if(wlrDB.CooldownExpand == "right") then 
					wlrDB.CooldownLeft = self:GetLeft()
					wlrDB.CooldownTop = self:GetTop() - (self:GetHeight() / 2)
				else
					wlrDB.CooldownLeft = self:GetLeft() + (self:GetWidth() /2)
					wlrDB.CooldownTop = self:GetTop()
				end 
			end
		end
	)
	
	for index, spell in pairs(CombatCDs) do
		local SpellId = tonumber(spell[1])
		CooldownIcons[SpellId] = self:CreateIcon(CooldownFrame, wlrDB.CooldownSize, wlrDB.CooldownAlpha, SpellId, wlrDB.CooldownFont, wlrDB.CooldownFontsize)
	end
	self:RefreshReminder(CooldownIcons, CooldownFrame, wlrDB.CooldownAlpha, wlrDB.CooldownSize, wlrDB.CooldownLeft, wlrDB.CooldownTop, wlrDB.CooldownFont, wlrDB.CooldownFontsize, wlrDB.CooldownExpand)
end

function WarlockReminder:UnlockFrame()
	if not UnlockDialog then
		local f = CreateFrame("Frame", "WlrUnlockDialog", UIParent)
		f:SetFrameStrata("DIALOG")
		f:SetToplevel(true)
		f:EnableMouse(true)
		f:SetClampedToScreen(true)
		f:SetWidth(360)
		f:SetHeight(110)
		f:SetBackdrop{
			bgFile="Interface\\DialogFrame\\UI-DialogBox-Background" ,
			edgeFile="Interface\\DialogFrame\\UI-DialogBox-Border",
			tile = true,
			insets = {left = 11, right = 12, top = 12, bottom = 11},
			tileSize = 32,
			edgeSize = 32,
		}
		f:SetPoint("TOP", 0, -50)
		f:Hide()

		local tr = f:CreateTitleRegion()
		tr:SetAllPoints(f)

		local header = f:CreateTexture(nil, "ARTWORK")
		header:SetTexture("Interface\\DialogFrame\\UI-DialogBox-Header")
		header:SetWidth(256); header:SetHeight(64)
		header:SetPoint("TOP", 0, 12)

		local title = f:CreateFontString("ARTWORK")
		title:SetFontObject("GameFontNormal")
		title:SetPoint("TOP", header, "TOP", 0, -14)
		title:SetText("WarlockReminder")

		local desc = f:CreateFontString("ARTWORK")
		desc:SetFontObject("GameFontHighlight")
		desc:SetJustifyV("TOP")
		desc:SetJustifyH("LEFT")
		desc:SetPoint("TOPLEFT", 18, -32)
		desc:SetPoint("BOTTOMRIGHT", -18, 48)
		desc:SetText(L["Frames unlocked. Move them now and click Lock when you are done."])

		local lockBars = CreateFrame("CheckButton", "WlrUnlockDialogLock", f, "OptionsButtonTemplate")
		getglobal(lockBars:GetName() .. "Text"):SetText(L["Lock"])

		lockBars:SetScript("OnClick", function(self)
			WarlockReminder:Lock()
			LibStub("AceConfigRegistry-3.0"):NotifyChange("WarlockReminder")
		end)

		--position buttons
		lockBars:SetPoint("BOTTOMRIGHT", -14, 14)

		UnlockDialog = f
	end
	UnlockDialog:Show()
end
-- END CreateFrames

function WarlockReminder:ResetReminder()
	wlrDB.ReminderTop = (UIParent:GetHeight()/2)
	wlrDB.ReminderLeft = (UIParent:GetWidth()/2)-64
	self:RefreshReminder(ReminderIcons, ReminderFrame, wlrDB.ReminderAlpha, wlrDB.ReminderSize, wlrDB.ReminderLeft, wlrDB.ReminderTop, wlrDB.ReminderFont, wlrDB.ReminderFontsize, wlrDB.ReminderExpand)
end

function WarlockReminder:ResetCombat()
	wlrDB.CombatTop = (UIParent:GetHeight()/2)
	wlrDB.CombatLeft = (UIParent:GetWidth()/2)
	self:RefreshReminder(CombatIcons, CombatFrame, wlrDB.CombatAlpha, wlrDB.CombatSize, wlrDB.CombatLeft, wlrDB.CombatTop, wlrDB.CombatFont, wlrDB.CombatFontsize, wlrDB.CombatExpand)
end

function WarlockReminder:ResetCooldown()
	wlrDB.CooldownTop = (UIParent:GetHeight()/2)
	wlrDB.CooldownLeft = (UIParent:GetWidth()/2)
	self:RefreshReminder(CooldownIcons, CooldownFrame, wlrDB.CooldownAlpha, wlrDB.CooldownSize, wlrDB.CooldownLeft, wlrDB.CooldownTop, wlrDB.CooldownFont, wlrDB.CooldownFontsize, wlrDB.CooldownExpand)
end

function WarlockReminder:ResetCustom()
	wlrDB.CustomTop = (UIParent:GetHeight()/2)
	wlrDB.CustomLeft = (UIParent:GetWidth()/2)+64
	self:RefreshReminder(CustomIcons, CustomFrame, wlrDB.CustomAlpha, wlrDB.CustomSize, wlrDB.CustomLeft, wlrDB.CustomTop, wlrDB.CustomFont, wlrDB.CustomFontsize, wlrDB.CustomExpand)
end

function WarlockReminder:Lock()
	ConfigMode = false
	UnlockDialog:Hide()
	self:ReminderFrameSetup()
	self:Reminder()
	self:CombatReminder()
	self:CooldownReminder()
	self:CustomReminder()
end

function WarlockReminder:Unlock()
	ConfigMode = true
	self:ReminderFrameSetup()
	self:UnlockFrame()
end

-- Frame Setup
function WarlockReminder:ReminderFrameSetup()
	if(ConfigMode == true) then 
		-- Reminder
		ReminderFrame:SetMovable(1)
		ReminderFrame:EnableMouse(1)
		ReminderIcons[DarkIntent]:Show()
		ReminderIcons["pets"]:Show()
		ReminderIcons[SoulLink]:Show()
		ReminderIcons[CurrentFlask]:Show()
		
		-- Cooldown
		CooldownFrame:SetMovable(1)
		CooldownFrame:EnableMouse(1)
		CooldownIcons[29858]:Show()
		CooldownIcons[110913]:Show()
		CooldownIcons[6229]:Show()
		
		-- Combat
		CombatFrame:SetMovable(1)
		CombatFrame:EnableMouse(1)
		CombatIcons[ShadowTrance]:Show()
		CombatIcons[DrainSoul]:Show()
		CombatIcons[MoltenCore]:Show()
		
		-- Custom
		local i = 0
		for index, _ in pairs(wlrDB.CustomSpells) do
			if (CustomIcons[index] ~= nil) then
				CustomIcons[index]:Show()
				i = i+1
				if(i > 5) then break end
			end
		end
		CustomFrame:SetMovable(1)
		CustomFrame:EnableMouse(1)
	else 
		ReminderFrame:SetMovable(0)
		ReminderFrame:EnableMouse(0)
		
		CombatFrame:SetMovable(0)
		CombatFrame:EnableMouse(0)
		
		CooldownFrame:SetMovable(0)
		CooldownFrame:EnableMouse(0)
		
		CustomFrame:SetMovable(0)
		CustomFrame:EnableMouse(0)
	end
	
	self:RefreshReminder(ReminderIcons, ReminderFrame, wlrDB.ReminderAlpha, wlrDB.ReminderSize, wlrDB.ReminderLeft, wlrDB.ReminderTop, wlrDB.ReminderFont, wlrDB.ReminderFontsize, wlrDB.ReminderExpand)
	self:RefreshReminder(CombatIcons, CombatFrame, wlrDB.CombatAlpha, wlrDB.CombatSize, wlrDB.CombatLeft, wlrDB.CombatTop, wlrDB.CombatFont, wlrDB.CombatFontsize, wlrDB.CombatExpand)
	self:RefreshReminder(CooldownIcons, CooldownFrame, wlrDB.CooldownAlpha, wlrDB.CooldownSize, wlrDB.CooldownLeft, wlrDB.CooldownTop, wlrDB.CooldownFont, wlrDB.CooldownFontsize, wlrDB.CooldownExpand)
	self:RefreshReminder(CustomIcons, CustomFrame, wlrDB.CustomAlpha, wlrDB.CustomSize, wlrDB.CustomLeft, wlrDB.CustomTop, wlrDB.CustomFont, wlrDB.CustomFontsize, wlrDB.CustomExpand)
end

local PetChoice = {
	["felhunter"] = L["Felhunter"],
	["succubus"] = L["Succubus"],
	["imp"] = L["Imp"],
	["voidwalker"] = L["Voidwalker"],
	["felguard"] = L["Felguard"],
}

-- Cooldownreminder spells
function WarlockReminder:GetCooldownSpells()
	local Spells = {}
	for index, spell in pairs(CombatCDs) do
		Spells[index] = GetSpellInfo(spell[1])
	end
	return Spells
end

function WarlockReminder:GetCurrentCooldown(info, key)
	return true, SelectedCooldowns[key];
end

function WarlockReminder:SetCurrentCooldown(info, key, value)
	if(not value) then
		value = nil;
	end

	SelectedCooldowns[key] = value;
end

-- Customreminder spells
function WarlockReminder:GetCustomSpells()
	local Spells = {}
	for index, spell in pairs(wlrDB.CustomSpells) do
		Spells[index] = GetSpellInfo(index)
	end
	return Spells
end

function WarlockReminder:GetCurrentSpells(info, key)
	return SelectedSpells[key];
end

function WarlockReminder:SetCurrentSpells(info, key, value)
	if(not value) then
		value = nil;
	end
	SelectedSpells[key] = value;
end

function WarlockReminder:AddCustomSpell(info, value)
	local found = false
	-- Spell already exists?
	for index, spell in pairs(wlrDB.CustomSpells) do
		if(index == tonumber(value)) then
			found = true
			break
		end
	end
	-- Spell not in list -> add spell
	if(found == false) then
		wlrDB.CustomSpells[tonumber(value)] = tonumber(value)
		if(not CustomIcons[tonumber(value)]) then
			CustomIcons[tonumber(value)] = self:CreateIcon(CustomFrame, wlrDB.CustomSize, wlrDB.CustomAlpha, tonumber(value), wlrDB.CustomFont, wlrDB.CustomFontsize)
		else
			CustomIcons[tonumber(value)]:Show()
		end
	end
end

function WarlockReminder:RemoveCustomSpell(info, value)
	if wlrDB.CustomSpells ~= nil then
		for index, _ in pairs(SelectedSpells) do
			CustomIcons[wlrDB.CustomSpells[index]]:Hide()
			wlrDB.CustomSpells[index] = nil
			table.remove(wlrDB.CustomSpells, index)
		end
	end
	SelectedSpells = {}

end

-- Options
local wlroptions = {
    name = "WarlockReminder",
    handler = WarlockReminder,
    type = "group",
	childGroups = "tree",
    args = {
    	config = {
			type = "execute",
			name = L["Configure"],
			desc = L["Open the options dialog of WarlockReminder"],
			func = function()
				InterfaceOptionsFrame_OpenToCategory(WarlockReminder.optionFrames.profile)
				InterfaceOptionsFrame_OpenToCategory(WarlockReminder.optionFrames.main)
			end,
			guiHidden = true,
		},
		configmode = {
			type = "execute",
			name = L["Config Mode"],
			desc = L["Config Mode"],
			func = "Unlock",
			guiHidden = true,
		},
		reminder = {
            type = "group",
			order = 10,
            name = L["Reminders"],
            args = {
				header = {
					type = "header",
					order = 1,
					name = L["Reminder Frame"],
				},
				enable = {
					type = "toggle",
					order = 2,
					name = L["Enable"],
					desc = L["Enable"],
					arg = "ReminderEnable",
					get = "getProfileOption",
					set = "setProfileOption",
				},
				spells = {
					type = "group",
					order = 10,
					name = L["Spell setup"],
						args = {
							reminderheader = {
								type = "header",
								order = 9,
								name = L["Reminders"],
							},
							darkintent = {
								type = "toggle",
								order = 15,
								name = L["Dark Intent"],
								desc = L["Dark Intent"],
								arg = "showDI",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							demonicrebirth = {
								type = "toggle",
								order = 17,
								name = L["Demonic Rebirth"],
								desc = L["Demonic Rebirth"],
								arg = "showDemonicRebirth",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							sl = {
								type = "toggle",
								order = 20,
								name = L["Soul Link"],
								desc = L["Show Soul Link reminder"],
								arg = "showSL",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							gos = {
								type = "toggle",
								order = 20,
								name = L["Grimoire of Sacrifice"],
								desc = L["Grimoire of Sacrifice"],
								arg = "showGOS",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							flask = {
								type = "toggle",
								order = 30,
								name = L["Flask"],
								desc = L["Show Flask reminder"],
								arg = "showFlask",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							food = {
								type = "toggle",
								order = 40,
								name = L["Well Fed"],
								desc = L["Show food reminder"],
								arg = "showFood",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							pet = {
								type = "toggle",
								order = 50,
								name = L["Pet"],
								desc = L["Show pet reminder"],
								arg = "showPet",
								get = "getProfileOption",
								set = "setProfileOption",
								width = "full",
							},
							afflictionpet = {
								type = "select",
								name = L["Affliction"],
								desc = L["Pet for Affliction"],
								order = 60,
								values = PetChoice,
								arg = "petAffliction",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							demonpet = {
								type = "select",
								name = L["Demonology"],
								desc = L["Pet for Demonology"],
								order = 70,
								values = PetChoice,
								arg = "petDemonology",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							destrupet = {
								type = "select",
								name = L["Destruction"],
								desc = L["Pet for Destruction"],
								order = 80,
								values = PetChoice,
								arg = "petDestruction",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							darkintentcombat = {
								type = "toggle",
								order = 90,
								name = L["Scan party/raid while in combat"],
								desc = L["Scan party/raid while in combat"],
								arg = "ScanPartyInCombat",
								get = "getProfileOption",
								set = "setProfileOption",
								width = "full",
							},
						},
				},
				frame = {
					type = "group",
					order = 10,
					name = L["Frame setup"],
					args = {
						header = {
							type = "header",
							order = 20,
							name = L["Reminder Frame"],
						},
						configmode = {
							type = "execute",
							name = L["Config Mode"],
							desc = L["Config Mode"],
							order = 30,
							func = "Unlock",
						},
						reset = {
							type = "execute",
							name = L["Reset position"],
							desc = L["Reset position"],
							order = 40,
							func = "ResetReminder",
						},
						alpha = {
							type = "range",
							name = L["Frame alpha"],
							desc = L["Frame alpha"],
							order = 50,
							min = 0.0,
							softMin = 0.25,
							max = 1.0,
							step = 0.05,
							isPercent = true,
							arg = "ReminderAlpha",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						size = {
							type = "range",
							name = L["Frame size"],
							desc = L["Frame size"],
							order = 60,
							min = 1,
							max = 500,
							softMax = 200,
							step = 1,
							isPercent = false,
							arg = "ReminderSize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						expand = {
							type = "select",
							name = L["Expand"],
							desc = L["Expand"],
							order = 65,
							values = {down = L["Down"], right = L["Right"]},
							arg = "ReminderExpand",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						timeleftheader = {
							type = "header",
							order = 69,
							name = L["Font settings"],
						},
						font = {
							type = 'select',
							dialogControl = 'LSM30_Font',
							name = L["Font"],
							desc = L["Font"],
							values = AceGUIWidgetLSMlists.font,
							arg = "ReminderFont",
							get = "getProfileOption",
							set = "setProfileOption",
							order = 80,
						},
						fontsize = {
							type = "range",
							name = L["Font size"],
							desc = L["Font size"],
							order = 90,
							min = 0.00,
							softMin = 7,
							max = 32,
							step = 1,
							arg = "ReminderFontsize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
					},
				}, -- END reminder frame setup
			}, -- END reminder
		},
		combat = {
            type = "group",
			order = 30,
            name = L["Combat Reminder"],
            args = {
				header = {
					type = "header",
					order = 1,
					name = L["Combat Frame"],
				},
				enable = {
					type = "toggle",
					order = 2,
					name = L["Enable"],
					desc = L["Enable"],
					arg = "CombatEnable",
					get = "getProfileOption",
					set = "setProfileOption",
				},
				frame = {
					type = "group",
					order = 10,
					name = L["Frame setup"],
					args = {
						anchorheader = {
							type = "header",
							order = 20,
							name = L["Combat Frame"],
						},
						configmode = {
							type = "execute",
							name = L["Config Mode"],
							desc = L["Config Mode"],
							order = 30,
							func = "Unlock",
						},
						reset = {
							type = "execute",
							name = L["Reset position"],
							desc = L["Reset position"],
							order = 40,
							func = "ResetCombat",
						},
						alpha = {
							type = "range",
							name = L["Frame alpha"],
							desc = L["Frame alpha"],
							order = 50,
							min = 0.0,
							softMin = 0.25,
							max = 1.0,
							step = 0.05,
							isPercent = true,
							arg = "CombatAlpha",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						size = {
							type = "range",
							name = L["Frame size"],
							desc = L["Frame size"],
							order = 60,
							min = 1,
							max = 500,
							softMax = 200,
							step = 1,
							isPercent = false,
							arg = "CombatSize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						expand = {
							type = "select",
							name = L["Expand"],
							desc = L["Expand"],
							order = 65,
							values = {down = L["Down"], right = L["Right"]},
							arg = "CombatExpand",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						timeleftheader = {
							type = "header",
							order = 69,
							name = L["Font settings"],
						},
						timeleft = {
							type = "toggle",
							name = L["Show time left"],
							desc = L["Show time left"],
							order = 70,
							arg = "showCombatTimeleft",
							get = "getProfileOption",
							set = "setProfileOption",
							width = "full",
						},
						font = {
							type = 'select',
							dialogControl = 'LSM30_Font',
							name = L["Font"],
							desc = L["Font"],
							values = AceGUIWidgetLSMlists.font,
							arg = "CombatFont",
							get = "getProfileOption",
							set = "setProfileOption",
							order = 80,
						},
						fontsize = {
							type = "range",
							name = L["Font size"],
							desc = L["Font size"],
							order = 90,
							min = 0.00,
							softMin = 7,
							max = 32,
							step = 1,
							arg = "CombatFontsize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
					},
				}, -- END combat frame setup
				spells = {
					type = "group",
					order = 30,
					name = L["Spell setup"],
					childGroups = "tab",
						args = {
						drainsoul = {
							type = "group",
							order = 20,
							name = L["Drain Soul"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "DrainSoulEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								percent = {
									type = "range",
									name = L["Show reminder at"],
									desc = L["Show Drain Soul reminder at"],
									order = 10,
									min = 0.0,
									max = 1.0,
									step = 0.01,
									isPercent = true,
									arg = "DrainSoulPercent",
									get = "getProfileOption",
									set = "setProfileOption",
								},
								health = {
									type = "input",
									name = L["Minimum health"],
									desc = L["Minimum health to show the Drain Soul reminder"],
									order = 20,
									arg = "DrainSoulHealth",
									get = "getProfileOption",
									set = "setProfileOption",
								},
								sound = {
									type = 'select',
									dialogControl = 'LSM30_Sound',
									name = L["Sound reminder"],
									desc = L["Play Drain Soul sound reminder"],
									order = 30,
									values = AceGUIWidgetLSMlists.sound,
									arg = "DrainSoulSound",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Drainsoul
						shadowtrance = {
							type = "group",
							order = 10,
							name = L["Shadow Trance"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "ShadowTranceEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								sound = {
									type = 'select',
									name = L["Sound reminder"],
									desc = L["Play Shadow Trance sound reminder"],
									order = 10,
									dialogControl = 'LSM30_Sound',
									values = AceGUIWidgetLSMlists.sound,
									arg = "ShadowTranceSound",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Shadow Trance
						shadowburn = {
							type = "group",
							order = 15,
							name = L["Shadowburn"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "ShadowburnEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								sound = {
									type = 'select',
									name = L["Sound reminder"],
									desc = L["Sound reminder"],
									order = 10,
									dialogControl = 'LSM30_Sound',
									values = AceGUIWidgetLSMlists.sound,
									arg = "ShadowburnSound",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Shadowburn
						backdraft = {
							type = "group",
							order = 20,
							name = L["Backdraft"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "BackdraftEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
							},
						}, -- END Backdraft
						conflagrate = {
							type = "group",
							order = 25,
							name = L["Conflagrate"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "ConflagrateEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
							},
						}, -- END Conflagrate
						moltencore = {
							type = "group",
							order = 30,
							name = L["Molten Core"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "MoltenCoreEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								sound = {
									type = 'select',
									name = L["Sound reminder"],
									desc = L["Play Molten Core sound reminder"],
									order = 10,
									dialogControl = 'LSM30_Sound',
									values = AceGUIWidgetLSMlists.sound,
									arg = "MoltenCoreSound",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Molten Core
						soulshards = {
							type = "group",
							order = 40,
							name = L["Soul Shards"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "SoulShardsEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								fadeout = {
									type = "range",
									name = L["Fadeout transparency"],
									desc = L["Fadeout transparency"],
									order = 10,
									min = 0,
									max = 1,
									step = 0.05,
									isPercent = true,
									arg = "SoulShardFadeout",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Soul Shards
						demonicfury = {
							type = "group",
							order = 50,
							name = L["Demonic Fury"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "DemonicFuryEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								fadeout = {
									type = "range",
									name = L["Fadeout transparency"],
									desc = L["Fadeout transparency"],
									order = 10,
									min = 0,
									max = 1,
									step = 0.05,
									isPercent = true,
									arg = "DemonicFuryFadeout",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Demonic Fury
						burningembers = {
							type = "group",
							order = 60,
							name = L["Burning Embers"],
							args = {
								enable = {
									type = "toggle",
									order  = 1,
									name = L["Enable"],
									desc = L["Enable"],
									arg = "BurningEmbersEnable",
									get = "getProfileOption",
									set = "setProfileOption",
									width = "full",
								},
								fadeout = {
									type = "range",
									name = L["Fadeout transparency"],
									desc = L["Fadeout transparency"],
									order = 10,
									min = 0,
									max = 1,
									step = 0.05,
									isPercent = true,
									arg = "BurningEmbersFadeout",
									get = "getProfileOption",
									set = "setProfileOption",
								},
								segment = {
									type = "toggle",
									order  = 20,
									name = L["Show Segments"],
									desc = L["Show Segments"],
									arg = "BurningEmbersSegment",
									get = "getProfileOption",
									set = "setProfileOption",
								},
							},
						}, -- END Burning Embers
					},
				}, -- END Spell Setup
			},
		}, -- End Combatreminder
		cooldown = {
            type = "group",
			order = 35,
            name = L["Cooldown Reminder"],
            args = {
				header = {
					type = "header",
					order = 1,
					name = L["Cooldown Frame"],
				},
				enable = {
					type = "toggle",
					order = 2,
					name = L["Enable"],
					desc = L["Enable"],
					arg = "CooldownEnable",
					get = "getProfileOption",
					set = "setProfileOption",
				},
				frame = {
					type = "group",
					order = 10,
					name = L["Frame setup"],
					args = {
						anchorheader = {
							type = "header",
							order = 20,
							name = L["Cooldown Frame"],
						},
						configmode = {
							type = "execute",
							name = L["Config Mode"],
							desc = L["Config Mode"],
							order = 30,
							func = "Unlock",
						},
						reset = {
							type = "execute",
							name = L["Reset position"],
							desc = L["Reset position"],
							order = 40,
							func = "ResetCooldown",
						},
						alpha = {
							type = "range",
							name = L["Frame alpha"],
							desc = L["Frame alpha"],
							order = 50,
							min = 0.0,
							softMin = 0.25,
							max = 1.0,
							step = 0.05,
							isPercent = true,
							arg = "CooldownAlpha",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						size = {
							type = "range",
							name = L["Frame size"],
							desc = L["Frame size"],
							order = 60,
							min = 1,
							max = 500,
							softMax = 200,
							step = 1,
							isPercent = false,
							arg = "CooldownSize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						expand = {
							type = "select",
							name = L["Expand"],
							desc = L["Expand"],
							order = 65,
							values = {down = L["Down"], right = L["Right"]},
							arg = "CooldownExpand",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						fadeout = {
							type = "range",
							name = L["Fadeout on cooldown"],
							desc = L["Fadeout on cooldown"],
							order = 70,
							min = 0,
							max = 1,
							step = 0.05,
							isPercent = true,
							arg = "CooldownFadeout",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						fontsetting = {
							type = "header",
							order = 79,
							name = L["Font settings"],
						},
						font = {
							type = 'select',
							dialogControl = 'LSM30_Font',
							name = L["Font"],
							desc = L["Font"],
							values = AceGUIWidgetLSMlists.font,
							arg = "CooldownFont",
							get = "getProfileOption",
							set = "setProfileOption",
							order = 80,
						},
						fontsize = {
							type = "range",
							name = L["Font size"],
							desc = L["Font size"],
							order = 90,
							min = 0.00,
							softMin = 7,
							max = 32,
							step = 1,
							arg = "CooldownFontsize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
					},
				}, -- END cooldown frame setup
				spells = {
					type = "group",
					order = 40,
					name = L["Spell setup"],
						args = {
							cooldownheader = {
								type = "header",
								order = 1,
								name = L["Cooldowns"],
							},
							showcd = {
								type = "toggle",
								order  = 2,
								name = L["Show remaining cooldown"],
								desc = L["Show remaining cooldown"],
								arg = "ShowCd",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							combat = {
								type = "toggle",
								order  = 3,
								name = L["Show only in combat"],
								desc = L["Show only in combat"],
								arg = "ShowCdOnlyInCombat",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							selectspell = {
								name = L["Spells"],
								type = "group",
								order = 10,
								dialogInline = true,
									args = CooldownOptions,
							},
					},
				}, -- END Cooldown Setup
			},
		}, -- End Cooldownreminder
		-- CustomReminder
		custom = {
			type = "group",
			order = 40,
			name = L["Custom Reminder"],
			args = {
				header = {
					type = "header",
					order = 1,
					name = L["Custom Frame"],
				},
				enable = {
					type = "toggle",
					order = 2,
					name = L["Enable"],
					desc = L["Enable"],
					arg = "CustomEnable",
					get = "getProfileOption",
					set = "setProfileOption",
				},
				spells = {
					type = "group",
					order = 20,
					name = L["Spell setup"],
						args = {
							combat = {
								type = "toggle",
								order  = 10,
								name = L["Show only in combat"],
								desc = L["Show only in combat"],
								arg = "ShowCustomOnlyInCombat",
								get = "getProfileOption",
								set = "setProfileOption",
							},
							addspell = {
								name = L["Add a Spell"],
								desc = L["Add a new spell to the list by entering the Spell-Id here."],
								type = "input",
								order = 20,
								get = false,
								set = "AddCustomSpell",
								width = "double",
							},
							selectspell = {
								name = "",
								desc = "",
								type = "multiselect",
								order = 30,
								get = "GetCurrentSpells",
								set = "SetCurrentSpells",
								values = "GetCustomSpells",
								width = "double",
							},
							removespell = {
								name = L["Remove Spell"],
								desc = L["Remove the selected spell from the list."],
								type = "execute",
								func = "RemoveCustomSpell",
								order = 40,
							},
							customdesc = {
								order = 100,
								name = L["Use spell-ids from wowhead.com's Urls, e.g. Devious Minds: http://www.wowhead.com/spell=70840 => Spell-Id: 70840"],
								type = "description",
							},
						},
				},
				frame = {
					type = "group",
					order = 10,
					name = L["Frame setup"],
					args = {
						configmode = {
							type = "execute",
							name = L["Config Mode"],
							desc = L["Config Mode"],
							order = 30,
							func = "Unlock",
						},
						reset = {
							type = "execute",
							name = L["Reset position"],
							desc = L["Anchor Reset"],
							order = 40,
							func = "ResetCustom",
						},
						sound = {
							type = 'select',
							name = L["Sound reminder"],
							desc = L["Sound reminder"],
							order = 50,
							dialogControl = 'LSM30_Sound',
							values = AceGUIWidgetLSMlists.sound,
							arg = "CustomSound",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						alpha = {
							type = "range",

							name = L["Frame alpha"],
							desc = L["Frame alpha"],
							order = 60,
							min = 0.0,
							softMin = 0.25,
							max = 1.0,
							step = 0.05,
							isPercent = true,
							arg = "CustomAlpha",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						size = {
							type = "range",
							name = L["Frame size"],
							desc = L["Frame size"],
							order = 70,
							min = 1,
							max = 500,
							softMax = 200,
							step = 1,
							isPercent = false,
							arg = "CustomSize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						expand = {
							type = "select",
							name = L["Expand"],
							desc = L["Expand"],
							order = 75,
							values = {down = L["Down"], right = L["Right"]},
							arg = "CustomExpand",
							get = "getProfileOption",
							set = "setProfileOption",
						},
						customtimeleftheader = {
							type = "header",
							order = 80,
							name = L["Show time left"],
						},
						timeleft = {
							type = "toggle",
							order = 90,
							name = L["Show time left"],
							desc = L["Show time left"],
							arg = "showCustomTimeleft",
							get = "getProfileOption",
							set = "setProfileOption",
							width = "full",
						},
						font = {
							type = 'select',
							dialogControl = 'LSM30_Font',
							name = L["Font"],
							desc = L["Font"],
							values = AceGUIWidgetLSMlists.font,
							arg = "CustomFont",
							get = "getProfileOption",
							set = "setProfileOption",
							order = 100,
						},
						fontsize = {
							type = "range",
							name = L["Font size"],
							desc = L["Font size"],
							order = 110,
							min = 0.00,
							softMin = 7,
							max = 32,
							step = 1,
							arg = "CustomFontsize",
							get = "getProfileOption",
							set = "setProfileOption",
						},
					},
				},
			},
		}, -- END CustomReminder
    },
}
-- END Options

function WarlockReminder:OnProfileChanged(event, database, newProfileKey)
	wlrDB = self.db.profile
	self:ReminderFrameSetup()
end

function WarlockReminder:OnProfileReset(event, database, newProfileKey)
	wlrDB = self.db.profile
	self:CreateDefaultTables()
	self:ResetReminder()
	self:ResetCustom()
	--self:Unlock()
end

function WarlockReminder:OnNewProfile(event, database, newProfileKey)
	wlrDB = self.db.profile
	self:CreateDefaultTables()
	--self:Unlock()
end

-- Setup options
function WarlockReminder:SetUpOptions()
	local wlrprofile = LibStub('AceDBOptions-3.0'):GetOptionsTable(self.db)
	-- Add dual-spec support
	local LibDualSpec = LibStub("LibDualSpec-1.0", true)
	if(LibDualSpec) then
		LibDualSpec:EnhanceDatabase(self.db, "WarlockReminder")
		LibDualSpec:EnhanceOptions(wlrprofile, self.db)
	end
	
	local config = LibStub("AceConfig-3.0")
	config:RegisterOptionsTable("WarlockReminder", wlroptions, {"wlr", "warlockreminder"})
	
	local registry = LibStub("AceConfigRegistry-3.0")
	-- Add option windows
	registry:RegisterOptionsTable("WarlockReminder Main", wlroptions)
	registry:RegisterOptionsTable("WarlockReminder Profiles", wlrprofile)
	
	local dialog = LibStub("AceConfigDialog-3.0")
	self.optionFrames = {
		main = dialog:AddToBlizOptions("WarlockReminder Main", "WarlockReminder"),
		profile = dialog:AddToBlizOptions("WarlockReminder Profiles", L["Profiles"], "WarlockReminder"),
	}
end

-- Get Function
function WarlockReminder:getProfileOption(info)
	return wlrDB[info.arg]
end
-- Dynamic, yes i know this all should be one function
function WarlockReminder:getDynamicOption(info)
	return wlrDB[info[#info]]
end

-- Set Function
function WarlockReminder:setProfileOption(info, value)
	wlrDB[info.arg] = value
	if(info.uiType == "cmd") then
		WarlockReminder:Print(L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"]:format(info.option.name, tostring(value)))
	end
end
 -- Dynamic
function WarlockReminder:setDynamicOption(info, value)
	wlrDB[info[#info]] = value   -- we use the db names in our settings for Zzz
	if(info.uiType == "cmd") then
		WarlockReminder:Print(L["|cffffff7f%s|r is now set to |cffffff7f[%s]|r"]:format(info[#info], tostring(value)))
	end
end

-- Color picker
function WarlockReminder:getProfileOptionColor(info)
	local c = wlrDB[info.arg]
	return c.r, c.g, c.b, c.a
end

function WarlockReminder:setProfileOptionColor(info, r, g, b, a)
	wlrDB[info.arg] = {["r"] = r, ["g"] = g, ["b"] = b, ["a"] = a}
end
